package com.hoshiicloud.suppplier.controller;

import com.hoshiicloud.common.exception.CommonError;
import com.hoshiicloud.common.exception.ServiceException;
import com.hoshiicloud.common.rpc.Response;
import com.hoshiicloud.common.utils.BeanUtils;
import com.hoshiicloud.common.utils.SMSCodeUtil;
import com.hoshiicloud.suppplier.entity.CategoryIdOrOrganizationId;
import com.hoshiicloud.suppplier.feign.FileObjectFeignService;
import com.hoshiicloud.suppplier.feign.IUsersService;
import com.hoshiicloud.suppplier.feign.IdGeneratorService;
import com.hoshiicloud.suppplier.feign.VeriCenterFeignService;
import com.hoshiicloud.user.dto.supppiler.*;
import com.hoshiicloud.user.param.supppiler.*;
import io.swagger.annotations.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.http.MediaType;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import java.util.ArrayList;
import java.util.List;

/**
 * @Author:campchen
 * @Date:Created in 下午 04:22 2019/6/19
 * @PACKAGENAME com.hoshiibuy.suppplier.controller
 * @Description
 */
@Slf4j
@Validated
@RestController
@RequestMapping("/suppplier/companyOrganization")
@Api(value = "租户供应商", tags = {"租户供应商聚合服务管理"})
public class CompanyOrganizationController {
    @Autowired
    private IUsersService usersService;

    @Autowired
    private IdGeneratorService idGeneratorService;

    @Autowired
    private VeriCenterFeignService veriCenterFeignService;

    @Autowired
    private FileObjectFeignService fileObjectFeignService;

    // 短信验证码失效时间
    @Value("${sms.expireSeconds}")
    private Long expireSeconds;

    /**
     * 新增供应商 同时添加其经营品类、附件，并且新增默认部门以及超级管理员 涉及供应商、经营品类、附件、部门、人员、部门人员关联表
     */
    //新增供应商
    @PostMapping("/addCompanyOrganization")
    @ApiOperation(value = "租户供应商新增")
    // @Transactional(rollbackFor = Exception.class)
    public Response addCompanyOrganization(@RequestBody AddCompanyOrganizationDTO dto) {
        Response rs;
        /**新增供应商*/
        try {
            rs = usersService.saveCompanyOrganization(dto.getComOrganizationAddParam());
            if (rs.getData() == null) {
                throw new ServiceException(rs.getMsg());
            }
        } catch (Exception e) {
            log.error("新增供应商" + "[" + e.getMessage() + "]");
            return Response.failed("新增供应商异常" + e.getMessage());
        }
        //获得供应商id
        Long vendorId = Long.parseLong(rs.getData().toString());


        /**新增经营类目*/
        List<ComOrganizationCategoryDTO> listCategory = new ArrayList<>();
        //获得新增经营品类的所有id
        List<Long> categoryIds = new ArrayList<>();
        dto.getListCategory().forEach(comOrganizationCategoryAddParam -> {
            ComOrganizationCategoryDTO comOrganizationCategoryDTO = null;
            try {
                comOrganizationCategoryDTO = BeanUtils.covertType(comOrganizationCategoryAddParam, ComOrganizationCategoryDTO.class);
            } catch (Exception e) {
                throw new ServiceException(CommonError.error("转换失败"));
            }
            Long id = Long.parseLong(idGeneratorService.queryGeneratorId());
            comOrganizationCategoryDTO.setId(id);
            listCategory.add(comOrganizationCategoryDTO);
            categoryIds.add(id);
        });
        try {
            rs = usersService.insertCategory4ComOrganization(listCategory);
            if (rs.getCode() != 200 || rs.getData() == null) {
                throw new ServiceException(rs.getMsg());
            }
        } catch (Exception e) {
            log.error("新增供应商经营品类异常" + "[" + e.getMessage() + "]");
            //删除刚增加的供应商基础信息
            usersService.deleteByComId(vendorId);
            return Response.failed("新增供应商经营品类异常" + e.getMessage());
        }



        /**新增附件*/
        List<ComOrganizationAttachDTO> list=new ArrayList<>();
        //获得新增附件的所有id
        List<Long> attachIds = new ArrayList<>();
        dto.getListAttach().forEach(comOrganizationAttachAddParam -> {
            ComOrganizationAttachDTO comOrganizationAttachDTO = null;
            try {
                comOrganizationAttachDTO = BeanUtils.covertType(comOrganizationAttachAddParam, ComOrganizationAttachDTO.class);
            } catch (Exception e) {
                throw new ServiceException(CommonError.error("转换失败"));
            }
            Long id=Long.parseLong(idGeneratorService.queryGeneratorId());
            comOrganizationAttachDTO.setId(id);
            comOrganizationAttachDTO.setVendorId(vendorId);
            list.add(comOrganizationAttachDTO);
            attachIds.add(id);
        });
        try {
            rs=usersService.insertAttach4ComOrganization(list);
            // rs = usersService.saveCompanyOrganizationAttach(comOrganizationAttachDTO);
            if (rs.getCode()!=200||rs.getData()==null) {
                throw new ServiceException(rs.getMsg());
            }
        } catch (Exception e) {
            log.error("新增供应商附件异常" + "[" + e.getMessage() + "]");
            //删除刚新增的经营领域
            usersService.deleteCategoryByIds(categoryIds);
            //删除刚增加的供应商基础信息
            usersService.deleteByComId(vendorId);
            return Response.failed("新增供应商附件异常" + e.getMessage());
        }


        //如果存在该租户会员获取其id 如不存在则新增并获取其id
        Response<Member> responseM = usersService.getMemberByMobile(dto.getComOrganizationAddParam().getCompanyId(),dto.getAdminMobile());
        if (responseM.getCode()!=200||responseM.getData()==null){
            //删除刚新增的附件
            usersService.deleteAttachByIds(attachIds);
            //删除刚新增的经营领域
            usersService.deleteCategoryByIds(categoryIds);
            //删除刚增加的供应商基础信息
            usersService.deleteByComId(vendorId);
            throw new ServiceException(rs.getMsg());
        }
        //获得会员id
        //获得关联租户会员与内部员工所需的id
        Long memberId =responseM.getData().getId();


        /**新增系统部*/
        ComOrganizationDepartmentesAddParam comOrganizationDepartmentesAddParam = new ComOrganizationDepartmentesAddParam();
        comOrganizationDepartmentesAddParam.setParentId(0L);
        comOrganizationDepartmentesAddParam.setOrganizationId(vendorId);
        comOrganizationDepartmentesAddParam.setMobile(dto.getAdminMobile());
        comOrganizationDepartmentesAddParam.setName(dto.getComOrganizationAddParam().getName());
        comOrganizationDepartmentesAddParam.setCharge("超级管理员");
        try {
            rs = usersService.saveCompanyOrganizationDepartmentes(comOrganizationDepartmentesAddParam);
            if (rs.getData() == null) {
                throw new ServiceException(rs.getMsg());
            }
        } catch (Exception e) {
            log.error("新增供应商部门异常" + "[" + e.getMessage() + "]");
            //删除刚新增的附件
            usersService.deleteAttachByIds(attachIds);
            //删除刚新增的经营领域
            usersService.deleteCategoryByIds(categoryIds);
            //删除刚增加的供应商基础信息
            usersService.deleteByComId(vendorId);
            return Response.failed("新增供应商部门异常" + e.getMessage());
        }
        //人员与部门关联
        Long departmentesId = Long.parseLong(rs.getData().toString());


        /**新增租户供应商系统部人员*/
        ComOrganizationUsersAddParam comOrganizationUsersAddParam = new ComOrganizationUsersAddParam();
        comOrganizationUsersAddParam.setMemberId(memberId);
        comOrganizationUsersAddParam.setMobile(dto.getAdminMobile());
        comOrganizationUsersAddParam.setPosition("超级管理员");
        try {
            rs = usersService.saveCompanyOrganizationUsers(comOrganizationUsersAddParam);
            if (rs.getData() == null) {
                throw new ServiceException(rs.getMsg());
            }
        } catch (Exception e) {
            log.error("新增供应商员工异常" + "[" + e.getMessage() + "]");
            //逻辑删除刚增加的供应商部门
            usersService.deleteByDepartmentId(departmentesId);
            //物理删除刚新增的附件
            usersService.deleteAttachByIds(attachIds);
            //物理删除刚新增的经营领域
            usersService.deleteCategoryByIds(categoryIds);
            //物理删除刚增加的供应商基础信息
            usersService.deleteByComId(vendorId);
            return Response.failed("新增供应商员工异常" + e.getMessage());
        }
        //人员与部门进行关联
        Long userId = Long.parseLong(rs.getData().toString());


        /**新增人员部门关联表*/
        ComOrganizationDepartmentesUsersAddParam comOrganizationDepartmentesUsersAddParam = new ComOrganizationDepartmentesUsersAddParam();
        comOrganizationDepartmentesUsersAddParam.setCompanyId(dto.getComOrganizationAddParam().getCompanyId());
        comOrganizationDepartmentesUsersAddParam.setDepartmentId(departmentesId);
        comOrganizationDepartmentesUsersAddParam.setRole("2");
        comOrganizationDepartmentesUsersAddParam.setEnabled(1);
        comOrganizationDepartmentesUsersAddParam.setUserId(userId);
        comOrganizationDepartmentesUsersAddParam.setCreatedBy("系统自动生成");
        try {
            rs = usersService.saveCompanyOrganizationDepartmentesUsers(comOrganizationDepartmentesUsersAddParam);
            if (rs.getData() == null) {
                throw new ServiceException(rs.getMsg());
            }
        } catch (Exception e) {
            log.error("新增供应商部门员工关联表异常" + "[" + e.getMessage() + "]");
            //逻辑删除刚增加的供应商用户
            usersService.deleteByUsersId(userId);
            //逻辑删除刚增加的供应商部门
            usersService.deleteByDepartmentId(departmentesId);
            //物理删除刚新增的附件
            usersService.deleteAttachByIds(attachIds);
            //物理删除刚新增的经营领域
            usersService.deleteCategoryByIds(categoryIds);
            //物理删除刚增加的供应商基础信息
            usersService.deleteByComId(vendorId);
            return Response.failed("新增供应商部门员工关联表异常" + e.getMessage());
        }
        return Response.data("新增成功");
    }

    /**
     * 在部门下添加人员及其角色，涉及人员、部门人员关联表
     */
    //租户供应商人员新增
    @PostMapping("/saveCompanyOrganizationUsers")
    @ApiOperation(value = "新增租户供应商人员")
    @Transactional(rollbackFor = Exception.class)
    public Response saveCompanyOrganizationUsers(@RequestBody AddCompanyOrganizationUsersDTO dto) {
        Response rs;
        //通过电话号码查询member是否存在 存在则返回memberId不存在则新增  租户id  部门id
        try {
            rs = usersService.saveCompanyOrganizationUsers(dto.getComOrganizationUsersAddParam());
            if (rs.getData() == null) {
                throw new ServiceException(rs.getMsg());
            }
        } catch (Exception e) {
            log.error("新增租户供应商人员异常" + "[" + e.getMessage() + "]");
            return Response.failed("新增租户供应商人员异常" + e.getMessage());
        }
        String userId = rs.getData().toString();
        /**将信息添加到部门 用户关联表。*/
        ComOrganizationDepartmentesUsersAddParam comOrganizationDepartmentesUsersAddParam = new ComOrganizationDepartmentesUsersAddParam();
        comOrganizationDepartmentesUsersAddParam.setCompanyId(dto.getCompanyId());
        comOrganizationDepartmentesUsersAddParam.setDepartmentId(dto.getDepartmentesId());
        comOrganizationDepartmentesUsersAddParam.setRole("2");
        comOrganizationDepartmentesUsersAddParam.setEnabled(1);
        comOrganizationDepartmentesUsersAddParam.setUserId(Long.parseLong(userId));
        comOrganizationDepartmentesUsersAddParam.setCreatedBy("系统自动生成");
        try {
            rs = usersService.saveCompanyOrganizationDepartmentesUsers(comOrganizationDepartmentesUsersAddParam);
            if (rs.getData() == null) {
                throw new ServiceException(rs.getMsg());
            }
        } catch (Exception e) {
            log.error("新增供应商部门员工关联表异常" + "[" + e.getMessage() + "]");
            return Response.failed("新增供应商部门员工关联表异常" + e.getMessage());
        }
        return Response.data("新增成功");
    }

    /**
     * 分页获取供应商列表
     */
    @PostMapping(value = "/getPage4CompanyOrganization")
    @ApiOperation(value = "分页获取租户供应商列表")
    public Response getPage4CompanyOrganization(@RequestParam String pageNumber, @RequestParam String pageSize) {
        Response rs;
        try {
            ComOrganizationQueryParam comOrganizationQueryParam = new ComOrganizationQueryParam();
            comOrganizationQueryParam.setPageNumber(pageNumber);
            comOrganizationQueryParam.setPageSize(pageSize);
            rs = usersService.getPage(comOrganizationQueryParam);
        } catch (Exception e) {
            log.error("分页获取租户供应商列表异常" + "[" + e.getMessage() + "]");
            rs = Response.failed("分页获取租户供应商列表" + e.getMessage());
        }
        return rs;
    }

    /**
     * 分页获取供应商列表
     */
    @PostMapping(value = "/getPage4CompanyOrganizationByStatus")
    @ApiOperation(value = "根据状态分页获取租户供应商列表")
    public Response<Page<ComOrganizationDTO>> getPage4CompanyOrganizationByStatus(@RequestParam Integer status, @RequestParam String pageNumber, @RequestParam String pageSize) {
        Response<Page<ComOrganizationDTO>> rs;
        try {
            ComOrganizationQueryParam poQueryParam = new ComOrganizationQueryParam();
            poQueryParam.setStatus(status);
            poQueryParam.setPageNumber(pageNumber);
            poQueryParam.setPageSize(pageSize);
            rs = usersService.getPage(poQueryParam);
        } catch (Exception e) {
            log.error("分页获取租户供应商列表异常" + "[" + e.getMessage() + "]");
            rs = Response.failed("根据状态分页获取租户供应商列表" + e.getMessage());
        }
        return rs;
    }

    /**
     * 根据id查询供应商详情
     */
    @ApiOperation(value = "根据id查询")
    @ApiParam(name = "id", value = "主键ID", required = true)
    @GetMapping("/{id}")
    public Response selectCompanyOrganization(@PathVariable("id") @Valid Long id) {
        return usersService.selectCompanyOrganization(id);
    }

    /**
     * 根据id修改供应商审核状态status
     */
    @PutMapping(value = "/comApproval")
    @ApiOperation(value = "根据id修改租户供应商审核状态status")
    public Response<ComOrganizationDTO> updateStatusByCompanyOrganizationId(@RequestParam Long id, @RequestParam Integer status) {
        Response response = usersService.comApproval(id, status);
        if (response.getData() == null || response.getCode() != 200) {
            throw new ServiceException(CommonError.error("更新失败"));
        }
        return response;
    }

    /**
     * 租户供应商修改
     */
    @PutMapping("/updateCompanyOrganization")
    @ApiOperation(value = "修改租户供应商信息")
    public Response updateCompanyOrganization(@RequestBody ComOrganizationUpdateParam param) {
        /*供应商修改自己信息时*/
        param.setStatus(0);
        Response response = usersService.update(param);
        if (response.getData() == null || response.getCode() != 200) {
            throw new ServiceException(CommonError.error("更新失败"));
        }
        return response;
    }

    /**
     * 租户供应商部门新增
     */
    @PostMapping("/saveCompanyOrganizationDepartmentes")
    @ApiOperation(value = "新增租户供应商部门")
    public Response saveCompanyOrganizationDepartmentes(@RequestBody ComOrganizationDepartmentesAddParam param) {
        if (param.getParentId() == null || param.getParentId() == 0L) {
            throw new ServiceException(CommonError.error("父id不能为空"));
        }
        Response response = usersService.saveCompanyOrganizationDepartmentes(param);
        if (response.getData() == null || response.getCode() != 200) {
            throw new ServiceException(CommonError.error("新增租户供应商部门失败"));
        }
        return response;
    }

    /**
     * 手动添加租户供应商部门与人员关联表新增
     */
    @PostMapping("/saveCompanyOrganizationDepartmentesUsers")
    @ApiOperation(value = "新增权限/新增租户供应商部门与人员关联表")
    public Response saveCompanyOrganizationDepartmentesUsers(@RequestBody ComOrganizationDepartmentesUsersAddParam param) {
        Response response = usersService.saveCompanyOrganizationDepartmentesUsers(param);
        if (response.getData() == null || response.getCode() != 200) {
            throw new ServiceException(CommonError.error("新增租户供应商部门人员关联表失败"));
        }
        return response;
    }





    /**
     *  获取供应商可选的 供应商经营类型
     */
    @PostMapping("/selectOrganizationTypeByOrgType/{orgType}")
    @ApiOperation(value = "根据机构获取供应商可选的经营类型")
    public Response selectOrganizationTypeByOrgType(@PathVariable("orgType") Integer orgType){
        return usersService.selectOrganizationTypeByOrgType(orgType);
    }


    /**
     *  获取供应商可选的 供应商经营品类
     */
    @PostMapping("/getPageCategory")
    @ApiOperation(value = "获取租户供应商可选的供应商经营品类")
    public Response getPage(@RequestBody ComOrganizationCategoryQueryParam param){
        return usersService.getPageCategory(param);
    }


    /**
     *  供应商经营类型选择应该上传的图片
     */
    @PostMapping("/getPageAttach")
    @ApiOperation(value = "供应商经营类型选择应该上传的图片")
    public Response getPage(@RequestBody ComOrganizationAttachQueryParam param){
        return usersService.getPageAttach(param);
    }



    /**
     * 发送验证码
     * @param mobile 手机号码
     * @return Response
     */
    @GetMapping("/mobile/{mobile}")
    @ApiOperation(value = "发送手机验证码", notes = "根据手机号码发送验证码", consumes = MediaType.ALL_VALUE)
    public Response verifCode(@PathVariable("mobile") String mobile) {
        Response<String> rs;
        try {
            // 生成手机6位验证码
            String code = SMSCodeUtil.code(4);
            Response send_rs = veriCenterFeignService.sendCode(mobile,code,expireSeconds);
            if (null != send_rs && send_rs.getCode() == 200 && null != send_rs.getData()) {
                rs = Response.data((String)send_rs.getData());
            } else {
                rs = Response.failed("短信验证码发送失败");
            }
        } catch (Exception e) {
            log.error("根据手机号码发送验证码异常"+"["+e.getMessage()+"]");
            rs = Response.failed(e.getMessage());
        }
        return rs;
    }

    /**上传一个文件*/
    @ApiOperation(value = "上传一个文件", notes = "传入已存在objectKey时将会覆盖原文件")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "bucketName",value = "存储空间名称，上传时指定的存储空间",paramType = "String",example = "obs-7d37"),
            @ApiImplicitParam(name = "objectKey",value = "文件key,上传时存储的对象key,如果key相同并且文件已存在，将覆盖文件，上传完毕后原样返回，如不传则使用文件MD5值。",paramType = "String"),
            @ApiImplicitParam(name = "fileName",value = "文件名,批量上传时需和key对应",paramType = "String"),
            @ApiImplicitParam(name = "folder",value = "文件夹路径",paramType = "String"),
            @ApiImplicitParam(name = "privateOwned",value = "对象私有读写,因没有设置的权限暂时无效",paramType = "Boolean",example = "false"),
            @ApiImplicitParam(name = "file",value = "文件",paramType = "formData",dataType = "MultipartFile"),
    })
    @PostMapping("/file/uploadFile")
    public Response uploadFile(@RequestParam("bucketName") String bucketName, @RequestParam("objectKey") String objectKey, @RequestParam("fileName") String fileName, @RequestParam("folder") String folder, @RequestParam("privateOwned") Boolean privateOwned , MultipartFile file){
        return fileObjectFeignService.uploadFile(bucketName,objectKey,fileName,folder,privateOwned,file);
    }

    @RequestMapping(value = "/user/idCardOcr",method = RequestMethod.POST)
    @ApiOperation(value = "身份证ocr识别接口",notes = "data正常返回内容见接口文档:https://market.aliyun.com/products/57124001/cmapi010401.html")
    @ApiImplicitParams({ @ApiImplicitParam(name = "image", value = "图片url或图片base64字符串", dataType = "String", required = true,example = ""),
            @ApiImplicitParam(name = "side", value = "身份证正反面 face或back", dataType = "String", required = true,example = "face") })
    public Response idCardOcrDiscern(@RequestParam("image") @NotBlank String image, @RequestParam("side") @NotBlank String side){
        return veriCenterFeignService.idCardOcrDiscern(image,side);
    }


    /**
     *  获取某个租户用户所关联的供应商列表
     */
    @GetMapping("/selectOrganizationByMemberId/{memberId}")
    @ApiOperation(value = "获取某个租户用户所关联的供应商列表")
    @ApiImplicitParam(name = "memberId", value = "会员id", dataType = "Long", required = true,example = "3486626619507810305")
    public Response selectOrganizationByMemberId(@PathVariable("memberId") Long memberId){
        return usersService.selectOrganizationByMemberId(memberId);
    }


    /**根据名称判断是否已存在*/
    @GetMapping("/find/{name}")
    @ApiOperation(value = "判断公司名称是否已经存在")
    @ApiImplicitParam(name = "name", value = "公司名称", dataType = "String", required = true,example = "好货严选供应商")
    public Response findByName(@PathVariable("name") String name){
        return usersService.findByName(name);
    }


    @PostMapping("/query/id")
    @ApiOperation(value = "根据类目id与类型id获取模板信息")
    @ApiImplicitParams({@ApiImplicitParam(name = "categoryIds",value = "类目Id",dataType = "List<Long>",required = true,example = "1,2"),
            @ApiImplicitParam(name = "organizationTypeId",value = "供应商经营类型id",dataType = "Long",required = true,example = "1")})
    public Response selectAttachmentTypeByCategoryIdOrOrganizationId(@RequestBody CategoryIdOrOrganizationId categoryIdOrOrganizationId){
        return usersService.selectAttachmentTypeByCategoryIdOrOrganizationId(categoryIdOrOrganizationId.getCategoryIds(),categoryIdOrOrganizationId.getOrganizationTypeId());
    }

    @GetMapping("/company/{id}")
    @ApiOperation(value = "根据租户id获取租户信息",hidden = true)
    public Response getCompanyById(@PathVariable("id") Long id){
        return usersService.getById(id);
    }

    @ApiOperation(value = "根据租户id获取租户部门信息")
    @GetMapping(value = "/company/department/{id}")
    public Response getComDepartmentsById(@PathVariable("id") Long id){
        return usersService.getComDepartmentsById(id);
    }
}
